package com.czy.blog.service;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import com.czy.blog.dao.FunctionDao;
import com.czy.blog.entity.Function;
import com.czy.blog.entity.Menu;
import com.czy.blog.vo.PageVo;

@Service
@Transactional
public class FunctionService {

	@Autowired
	private FunctionDao functionDao;
	@Autowired
	private MenuService menuService;

	public Function findByMenuAndFuncCode(Menu menu, String funCode)
	{
		return functionDao.findByMenuAndFuncCode(menu,funCode);
	}

	public void deleteAll()
	{
		functionDao.deleteAll();
	}

	public Function findById(String id)
	{
		return functionDao.findOne(id);
	}

	public void delete(List<String> ids)
	{
		Iterable<Function> funcs = functionDao.findAll(ids);
		functionDao.delete(funcs);
	}

	public List<Function> findByMenuId(String id,PageVo pageVo)
	{
		if(StringUtils.isEmpty(id)){
			new ArrayList<Function>();
		}
		
		int pageNo = pageVo.getPage() - 1;
		Pageable page = new PageRequest(pageNo < 0 ? 0 : pageNo,pageVo.getRows());
		Page<Function> pageContent =  functionDao.findAll(findByCondition(id),page);
		return pageContent.getContent();
	}
	
	public Specification<Function> findByCondition(final String menuId){
		return new Specification<Function>() {
			@Override
			public Predicate toPredicate(Root<Function> root,CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> ps = new ArrayList<Predicate>();
				Join<Menu,Function> menu = root.join("menu",JoinType.LEFT);
				
				ps.add(cb.equal(menu.<String> get("id"), menuId));
				return cb.and(ps.toArray(new Predicate[0]));
			}
		};
	}

	public List<Function> findAll()
	{
		return (List<Function>) functionDao.findAll();
	}

	public void save(Function func, String menuId)
	{
		Menu menu = menuService.findById(menuId);
		func.setMenu(menu);
		functionDao.save(func);
	}

	public void update(Function func)
	{
		functionDao.save(func);
	}

	public List<Function> findByIds(List<String> funcIds)
	{
		return (List<Function>) functionDao.findAll(funcIds);
	}
}
